// 数据管理模块

import networkService from './network-service.js';
import errorHandler, { ErrorType, ErrorSeverity } from './error-handler.js';

// 添加计数器，用于跟踪loadData函数的调用次数
let loadDataCounter = 0;

// 防抖动相关变量
const STORAGE_KEY = 'lastLoadDataTime';
const MIN_TIME_BETWEEN_CALLS = 10000; // 两次调用之间的最小时间间隔（毫秒）
let debounceTimer = null;

// 从localStorage获取最后一次请求时间，如果没有则使用当前时间
let lastLoadDataTime = 0;

// 尝试从localStorage中恢复上次请求时间
function getLastLoadDataTime() {
  try {
    if (typeof localStorage !== 'undefined') {
      const storedTime = localStorage.getItem(STORAGE_KEY);
      if (storedTime) {
        return parseInt(storedTime, 10);
      }
    }
  } catch (error) {
    console.warn('无法从localStorage读取数据:', error);
  }
  return Date.now();
}

// 保存最后一次请求时间到localStorage
function saveLastLoadDataTime(time) {
  try {
    if (typeof localStorage !== 'undefined') {
      localStorage.setItem(STORAGE_KEY, time.toString());
    }
  } catch (error) {
    console.warn('无法保存数据到localStorage:', error);
  }
}

// 初始化lastLoadDataTime
lastLoadDataTime = getLastLoadDataTime();

/**
 * 在页面上显示日志信息
 * @param {string} message - 日志消息
 * @param {Object} details - 详细信息
 */
function displayLogOnPage(message, details) {
  try {
    // 确保DOM已加载
    if (!document || !document.body) {
      return;
    }
    
    // 查找或创建日志容器
    let logContainer = document.getElementById('dataLoadLogContainer');
    if (!logContainer) {
      // 创建一个新的日志容器
      logContainer = document.createElement('div');
      logContainer.id = 'dataLoadLogContainer';
      logContainer.style.cssText = `
        position: fixed;
        bottom: 20px;
        right: 20px;
        width: 300px;
        max-height: 400px;
        background: rgba(0, 0, 0, 0.8);
        color: white;
        padding: 10px;
        border-radius: 8px;
        font-size: 12px;
        overflow-y: auto;
        z-index: 10000;
        font-family: monospace;
      `;
      
      // 添加标题
      const title = document.createElement('h4');
      title.textContent = '数据加载日志';
      title.style.margin = '0 0 10px 0';
      title.style.padding = '0';
      logContainer.appendChild(title);
      
      document.body.appendChild(logContainer);
    }
    
    // 创建日志条目
    const logEntry = document.createElement('div');
    logEntry.style.cssText = 'margin-bottom: 8px; padding-bottom: 8px; border-bottom: 1px solid rgba(255,255,255,0.2);';
    
    // 添加消息和详细信息
    logEntry.innerHTML = `
      <div><strong>${message}</strong></div>
      <div style="font-size: 11px; color: #ccc;">${details.timestamp}</div>
      <div style="font-size: 11px; color: #aaa;">URL: ${details.url}</div>
    `;
    
    // 将日志条目添加到容器的顶部
    if (logContainer.firstChild.nextSibling) {
      logContainer.insertBefore(logEntry, logContainer.firstChild.nextSibling);
    } else {
      logContainer.appendChild(logEntry);
    }
    
    // 限制日志条目数量
    const maxEntries = 20;
    while (logContainer.children.length > maxEntries + 1) { // +1 for title
      logContainer.removeChild(logContainer.lastChild);
    }
  } catch (error) {
    // 如果创建日志容器失败，就记录到控制台
    console.error('无法在页面上显示日志:', error);
  }
}

/**
 * 加载示例数据
 * @param {string} url - 数据URL
 * @param {function(Object)} onSuccess - 成功回调
 * @param {function(Error)} onError - 失败回调
 */
export async function loadData(url = '/mock-data.json', onSuccess, onError) {
  // 检查距离上次调用的时间
  const currentTime = Date.now();
  const timeSinceLastCall = currentTime - lastLoadDataTime;
  
  // 如果时间间隔太短，使用防抖动机制
  if (timeSinceLastCall < MIN_TIME_BETWEEN_CALLS) {
    console.log(`🔴 loadData 调用被防抖动限制: 上次调用仅 ${timeSinceLastCall}ms 前`);
    
    // 如果已经有防抖动定时器，清除它
    if (debounceTimer) {
      clearTimeout(debounceTimer);
    }
    
    // 设置新的防抖动定时器，延迟到最小间隔后执行
    debounceTimer = setTimeout(() => {
      console.log(`🟡 loadData 防抖动执行`);
      loadDataInternal(url, onSuccess, onError);
    }, MIN_TIME_BETWEEN_CALLS - timeSinceLastCall);
    
    return Promise.resolve(getFallbackData()); // 返回备用数据，避免等待
  }
  
  // 如果时间间隔足够长，直接执行
  return loadDataInternal(url, onSuccess, onError);
}

/**
 * loadData的内部实现，包含实际的数据加载逻辑
 * @private
 */
async function loadDataInternal(url = '/mock-data.json', onSuccess, onError) {
  // 更新上次调用时间
  lastLoadDataTime = Date.now();
  // 保存到localStorage，确保页面刷新后也能保持防抖动状态
  saveLastLoadDataTime(lastLoadDataTime);
  
  // 增加计数器
  loadDataCounter++;
  
  // 记录调用信息
  const timestamp = new Date().toISOString();
  const logDetails = { url, timestamp };
  console.log(`🟢 loadData 调用 #${loadDataCounter}`, logDetails);
  
  // 在页面上显示日志信息
  displayLogOnPage(`loadData 调用 #${loadDataCounter}`, logDetails);
  
  try {
    const options = {
      headers: {
        Accept: 'application/json',
      },
      retryOptions: {
        maxRetries: 3,
        retryDelay: 1000,
        exponentialBackoff: true, // 添加指数退避重试
        retryableStatusCodes: [408, 429, 500, 502, 503, 504] // 仅重试特定状态码
      },
      timeout: 10000 // 设置10秒超时
    };
    
    // 使用network-service的get方法，它会自动处理重试和离线情况
    const data = await networkService.get(url, options);
    
    // 检查是否是排队的请求
    if (data && data._queued) {
      console.log('请求已加入队列，网络恢复时将自动同步:', data.message);
      if (onError) {
        onError(new Error('请求已排队'), getFallbackData());
      } else if (onSuccess) {
        onSuccess(getFallbackData());
      }
      return getFallbackData();
    }
    
    if (onSuccess) {
      onSuccess(data);
    }
    return data;
  } catch (error) {
    // 使用统一的错误处理模块记录和处理错误
    const errorInfo = errorHandler.handleError(
      error,
      ErrorType.NETWORK,
      ErrorSeverity.WARNING,
      { context: '数据加载', url }
    );

    // 使用备用数据
    const fallbackData = getFallbackData();

    if (onError) {
      onError(errorInfo, fallbackData);
    } else if (onSuccess) {
      onSuccess(fallbackData);
    }

    return fallbackData;
  }
}

/**
 * 获取备用数据
 * @returns {Object} 备用数据对象
 */
function getFallbackData() {
  return {
    app: 'PWA + Workbox 示例应用',
    version: 'v2.1',
    status: '使用备用数据',
    features: ['离线缓存', '自动更新', '后台同步', '安装到桌面', '网络状态检测'],
    lastUpdated: new Date().toISOString(),
  };
}

/**
 * 显示数据到UI
 * @param {Object} data - 要显示的数据
 * @param {string} containerId - 容器元素ID
 */
export function displayData(data, containerId = 'appContent') {
  const container = document.getElementById(containerId);
  if (!container) return;

  // 格式化数据显示
  const formattedData = JSON.stringify(data, null, 2);
  container.innerHTML = `<pre>${formattedData}</pre>`;
}
